package domain.worm;

import com.uqbar.vainilla.DeltaState;
import components.CircularShape;
import components.Shape;

import domain.components.WormsComponent;
import domain.weapon.Bazooka;
import domain.weapon.Explosion;
import domain.weapon.Weapon;






// HACER UN METODO WALK QUE SE MUEVA DIRECTAMENTE Y NO HAGA UN COLLIDE



public class Worm extends WormsComponent{

	private int moveCap;
	private double speed;
	private double fallSpeed;
	private WormState state;
	private int dir= -1;
	private Weapon weapon;
	private double health;
	private int teamId = 0;
	
	//appearence, habr�a que cambiarlo de lugar. Lo qe mismo que las inicializaciones

	
	public Worm(double x, double y) {
		super(22, 22, x, y);
		this.setZ(10);
		this.state = new StateFalling(this);
		moveCap = -10;
		speed = 100;
		fallSpeed = 100;
		this.health = 100; //configurable
		this.weapon = new Bazooka();
	}


	@Override
	public boolean isSolid() {
		return true;
	}

	@Override
	protected void onCollisionWithSolid(WormsComponent gc) {
	}

	@Override
	protected void defineCollide(WormsComponent gc) {
		gc.collideWithWorm(this);
	}



	public boolean fall(DeltaState deltaState) {
		double nX = deltaState.getDelta()*this.getFallSpeed()+this.getX();
		double nY = deltaState.getDelta()*this.getFallSpeed()+this.getY();
		
		
		if(!this.getScene().getTerrain().isCollision(nX, nY, this.getDiameter(), this.getHeight())){
			//this.updateCoords(0, deltaState.getDelta()*this.getFallSpeed());
			this.generciMove(deltaState, this.getFallSpeed(), 0, 1);
			return true;
		}
		return false;
	}

	public int getMoveCap() {
		return moveCap;
	}

	public void setMoveCap(int moveCap) {
		this.moveCap = moveCap;
	}

	public double getFallSpeed() {
		return fallSpeed;
	}

	public void setFallSpeed(double fallSpeed) {
		this.fallSpeed = fallSpeed;
	}

	public WormState getState() {
		return state;
	}

	public void setState(WormState state) {
		this.state = state;
	}

	public double getSpeed() {
		return this.speed;
	}


	public void setDir(int dir) {
		this.dir = dir;
	}

	public int getDir() {
		return dir;
	}
	public boolean canWalk(DeltaState delta, int dir) {
		double nX, nY;
		nX = this.getX() + delta.getDelta()*this.getSpeed()*dir + dir;
		nY = this.getY() -1;
		
		return !this.getScene().getTerrain().isCollision(nX, nY, this.getDiameter(), this.getHeight());
	}
	
	public void collideWithExplosion(Explosion explosion) {
		double dmg = explosion.calculateDamage(this);
		this.damage(dmg);
	}

	@Override
	public Shape defineShape() {
		return new CircularShape(this);
	}

	public double getHealth() {
		return health;
	}

	public void setHealth(double health) {
		this.health = health;
	}
	
	public void damage (double dmg){
		this.getScene().wormDamaged(this, dmg);
		this.setHealth(this.getHealth() - dmg);
		if(this.getHealth() <= 0){
			this.die();
		}
	}

	public boolean isAlive(){
		return this.getHealth() >0;
	}

	public synchronized void die() {
			this.setHealth(-1);
			this.getState().toDead();
			this.getScene().wormDied(this);
	}


	public void walk(DeltaState delta, int dir) {
		this.getState().walk(delta, dir);
	}

	public void setStill() {
		this.getState().toStandBy();
	}

	public void jump() {
		this.getState().jump();
	}

	public void aim() {
		this.getState().aim();
	}
	public void fall(){
		this.getState().toFallingState();
	}

	public Weapon getWeapon() {
		return weapon;
	}

	public void setWeapon(Weapon weapon) {
		this.weapon = weapon;
	}


	@Override
	protected void effectiveUpdate(DeltaState deltaState) {
		if (this.fall(deltaState)){
			this.getState().toFallingState();
		}
		
		this.getState().update(deltaState);
		

	}
	
	public void showTeam(){
		this.getScene().teamId(this);
	}
	
	public void dissembleTeam(){
		this.getScene().removeTeamId(this);
	}

	public void showPower(double power) {
		this.getScene().powerWeapon(this, power);
	}
	
	public double getLimitPowerWeapon(){
		return this.getWeapon().getLimitPowerWeapon();
	}


	public void setTeamId(int teamId) {
		this.teamId = teamId;
	}


	public int getTeamId() {
		return teamId;
	}


	public void showIndicador() {
		this.getScene().indicador(this);		
	}
	public void dissembleIndicador(){
		this.getScene().removeIndicador();
	}
}
